package com.hongkuncheng.cms.aspect;

import com.hongkuncheng.cms.exception.FailException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Aspect
@Component
public class ControllerAspect {

    @Pointcut("execution(* com.hongkuncheng.cms.controller.*Controller.*(..)) " +
            "|| execution(* com.hongkuncheng.cms.controller.*.*Controller.*(..))*")
    void pointcut() {
    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) throws InvocationTargetException, IllegalAccessException {

        ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attrs.getRequest();

        Enumeration<String> parameterNames = request.getParameterNames();
        Pattern commentsPattern = Pattern.compile("<!--.*?-->", Pattern.CASE_INSENSITIVE);
        while (parameterNames.hasMoreElements()) {
            String parameterName = parameterNames.nextElement();
            String parameterValue = request.getParameter(parameterName);
            Matcher commentsMatcher = commentsPattern.matcher(parameterValue);
            parameterValue = commentsMatcher.replaceAll("");
            Pattern iframePattern = Pattern.compile("<[\\s]*?iframe[^>]*?>[\\s\\S]*?<\\/iframe>", Pattern.CASE_INSENSITIVE);
            Matcher iframeMatcher = iframePattern.matcher(parameterValue);
            parameterValue= iframeMatcher.replaceAll("");
            Pattern stylePattern = Pattern.compile("<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>", Pattern.CASE_INSENSITIVE);
            Matcher styleMatcher = stylePattern.matcher(parameterValue);
            parameterValue = styleMatcher.replaceAll("");
            Pattern execPattern = Pattern.compile("<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>", Pattern.CASE_INSENSITIVE);
            Matcher execMatcher = execPattern.matcher(parameterValue);
            while (execMatcher.find()) throw new FailException("禁止提交包含<script>的内容");
            execPattern = Pattern.compile("script:", Pattern.CASE_INSENSITIVE);
            execMatcher = execPattern.matcher(parameterValue);
            while (execMatcher.find()) throw new FailException("禁止提交包含script:的内容");
            execPattern = Pattern.compile("on([a-zA-Z]+)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            execMatcher = execPattern.matcher(parameterValue);
            while (execMatcher.find()) throw new FailException("禁止提交包含js事件的内容");
            execPattern = Pattern.compile("data:", Pattern.CASE_INSENSITIVE);
            execMatcher = execPattern.matcher(parameterValue);
            while (execMatcher.find()) throw new FailException("禁止提交包含data:的内容");
            execPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            execMatcher = execPattern.matcher(parameterValue);
            while (execMatcher.find()) throw new FailException("禁止提交包含eval的内容");
            execPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            execMatcher = execPattern.matcher(parameterValue);
            while (execMatcher.find()) throw new FailException("禁止提交包含expression的内容");
        }

    }

}
